<template>
  <div class="book-box">
    <div class="search-box">
      <el-input v-model="queryBookForm.bookNo" placeholder="请输入书籍编号搜索" clearable/>
      <el-input v-model="queryBookForm.bookName" placeholder="请输入书籍名称搜索" clearable/>
      <el-button type="primary" @click="queryBookList">点击查询</el-button>
      <el-button type="danger" @click="testDownload">测试下载</el-button>
    </div>
    <el-table :data="bookList" style="width: 100%">
      <el-table-column prop="bookNo" label="编号" width="180"></el-table-column>
      <el-table-column prop="bookName" label="书名" width="180"></el-table-column>
      <el-table-column prop="bookAuthor" label="作者" width="180"></el-table-column>
      <el-table-column prop="typeName" label="书籍类型" width="180"></el-table-column>
      <el-table-column prop="createDate" label="创建日期"></el-table-column>
      <el-table-column label="操作">
        <template slot-scope="scope">
          <el-button @click="queryBookDetail(scope.row)" type="warning" size="small">查看详情</el-button>
        </template>
      </el-table-column>
    </el-table>
    <el-pagination
      style="margin-top: 8px"
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
      :current-page="queryBookForm.pageNo"
      :page-sizes="[10, 20, 30, 40]"
      :page-size="queryBookForm.pageSize"
      layout="total, sizes, prev, pager, next, jumper"
      :total="totals">
    </el-pagination>
    <el-dialog
      title="书籍详情"
      :visible.sync="bookDetailDialogVisible"
      width="40%">
      <el-form ref="addBookForm" :model="selectBookDetail" label-width="80px">
        <el-form-item label="书籍编号" prop="bookNo">
          <el-input v-model="selectBookDetail.bookNo" clearable></el-input>
        </el-form-item>
        <el-form-item label="书籍名称" prop="bookName">
          <el-input v-model="selectBookDetail.bookName" clearable></el-input>
        </el-form-item>
        <el-form-item label="作者" prop="bookAuthor">
          <el-input v-model="selectBookDetail.bookAuthor" clearable></el-input>
        </el-form-item>
        <el-form-item label="书籍封面" prop="bookAvatar">
          <img width="100px" height="100px" :src="selectBookDetail.fileUrl" alt="预览" />
          <div class="img-box">
            <el-button type="success" size="mini" @click="downloadImage(selectBookDetail.fileUrl, 'blob')">点击下载图片(bolb流式下载)</el-button>
            <el-button type="success" size="mini" @click="downloadImage(selectBookDetail.fileUrl, 'base64')">点击下载图片(base64下载)</el-button>
          </div>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="bookDetailDialogVisible = false">关 闭</el-button>
        <el-button type="primary" @click="confirmUpdateBookInfo">确 定 修 改</el-button>
      </span>
    </el-dialog>
  </div>
</template>
<script>
export default {
  data() {
    return {
      queryBookForm:{
        "bookNo": "",
        "bookName": "",
        "pageNo": 1,
        "pageSize": 10
      },
      bookList: [],
      totals: 0,
      selectBookDetail: {},
      bookDetailDialogVisible: false
    }
  },
  created() {
    this.queryBookList()
  },
  methods: {
    queryBookList(){
      this.$http.post('/book/queryBooks', this.queryBookForm).then(res => {
        if (res.data){
          this.bookList = res.data.bookList
          this.totals = res.data.totals
        }
      })
    },
    handleSizeChange(val) {
      this.queryBookForm.pageSize = val
      this.queryBookList()
    },
    handleCurrentChange(val) {
      this.queryBookForm.pageNo = val
      this.queryBookList()
    },
    queryBookDetail(book){
      this.selectBookDetail = book
      console.log('书籍信息==>', this.selectBookDetail)
      this.bookDetailDialogVisible = true
    },
    confirmUpdateBookInfo() {},
    downloadImage(url, downloadMode){
      // downloadMode下载模式：blob(数据流)、base64
      let responseType = null
      if (downloadMode === 'blob'){
        responseType = 'blob'
      }
      this.$http.get('/book/downloadImage', {
        params: {"fileUrl": url, "downloadMode": downloadMode}, 
        responseType: responseType
      }).then(res => {
        // 方案一、返回blob格式下载
        if (downloadMode === 'blob') {
          const contentDisposition = res.headers['content-disposition']
          let filename = this.parseFilenameFromContentDisposition(contentDisposition)
          filename = filename ? filename : 'downloaded_image.jpg'
          const blob = new Blob([res.data], { type: 'application/octet-stream' })
          const link = document.createElement('a')
          link.href = URL.createObjectURL(blob)
          link.download = filename
          link.click()
          URL.revokeObjectURL(link.href)
          this.$message.success('下载成功')
        } else if (downloadMode === 'base64'){
          // 方案二、base64下载
          const base64Data = res.data.imageBase64
          const fileName = res.data.fileName
          this.downloadBase64File(base64Data, fileName)

          this.$message.success(res.msg || '下载成功')
        }  
      })
    },
    base64toBlob(base64, type = 'application/octet-stream') {
      const bstr = atob(base64) // atob方法是JavaScript的全局函数，用于将Base64编码的字符串解码为原始二进制数据。
      let n = bstr.length
      const u8arr = new Uint8Array(n) //处理二进制数据；new Uint8Array是 JavaScript 中表示8位无符号整型数组的类型
      while (n--) {
        u8arr[n] = bstr.charCodeAt(n) // charCodeAt() 方法可返回指定位置的字符的 Unicode 编码，返回值是 0 - 65535 之间的整数，表示给定索引处的 UTF-16 代码单元
      }
      return new Blob([u8arr], { type })
    },
    downloadBase64File(base64Data, fileName){
      var blob = this.base64toBlob(base64Data)
      const url = URL.createObjectURL(blob)
      const a = document.createElement('a')
      a.style.display = 'none'
      a.href = url
      a.download = fileName
      document.body.appendChild(a)
      a.click()
      document.body.removeChild(a)
      URL.revokeObjectURL(url)
    },
    testDownload(){
      this.$http.get('/book/downloadTest', { responseType: 'blob'}).then(res =>{
        console.log('测试下载==>', res)
        const contentDisposition = res.headers['content-disposition']
        let filename = this.parseFilenameFromContentDisposition(contentDisposition)
        filename = filename ? filename : 'downloaded_image.jpg'
        const blob = new Blob([res.data], { type: 'application/octet-stream' })
        const link = document.createElement('a')
        link.href = URL.createObjectURL(blob)
        link.download = filename
        link.click()
        URL.revokeObjectURL(link.href)
      })
    },
    parseFilenameFromContentDisposition(contentDisposition) {
      if (!contentDisposition) {
        return 'unknown';
      }

      const regex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/;
      const matches = regex.exec(contentDisposition);

      if (matches && matches[1]) {
        let filename = matches[1].trim();

        // 如果 filename 被引号包围，去掉引号
        if (filename.startsWith('"') && filename.endsWith('"')) {
          filename = filename.slice(1, -1);
        }

        return filename;
      }

      return 'unknown';
    }
  }
}
</script>
<style scoped>
.book-box{
    width: 100%;
    height: 100%;
}
.book-box .search-box .el-input{
    width: 30%;
    margin-right: 20px;
    margin-bottom: 10px;
}
</style>